from 程序核心代码.mvvm重构.基础定义.节点管理器.动态数据调度器.属性管理器 import 属性管理基类
import logging

# 配置日志记录器
logging.basicConfig(level=logging.WARNING, format='%(asctime)s - %(levelname)s - %(message)s')
日志记录器 = logging.getLogger(__name__)

class 状态机管理(属性管理基类):
    def __init__(self):
        super().__init__()
        self.状态机字典 = {}
        self.调试模式 = False
        # 设置日志等级
        if self.调试模式:
            日志记录器.setLevel(logging.DEBUG)
            日志记录器.debug(f"{self.__class__.__name__}调试模式已开启")
        else:
            日志记录器.setLevel(logging.ERROR)  # 只显示警告及以上级别的日志

    def 注册状态机(self, 状态机名称: str):
        if 状态机名称 in self.状态机字典:
            raise ValueError(f"状态机管理器：{状态机名称} 已存在，无法重复注册")
        self.状态机字典[状态机名称] = 状态机(self, 状态机名称)
        日志记录器.info(f"状态机管理器：{状态机名称} 注册成功")

    def 注册状态(self, 状态机名称: str, 状态名称: str, 连续状态=False, 前置属性列表=None, 后置属性列表=None, 动作=None):
        if 状态机名称 not in self.状态机字典:
            raise ValueError(f"状态机管理器：{状态机名称} 不存在")
        _状态 = self.状态机字典[状态机名称].注册状态(状态名称, 连续状态)
        if 动作 is not None:
            _状态.设置状态动作(动作)
        if 前置属性列表 is not None:
            for 属性名称 in 前置属性列表:
                _状态.前置属性注册(属性名称)
        if 后置属性列表 is not None:
            for 属性名称 in 后置属性列表:
                _状态.后置属性注册(属性名称)
        日志记录器.info(f"状态机：{状态机名称} 中状态：{状态名称} 注册成功")

    def 获取状态机(self, 状态机名称: str):
        if 状态机名称 not in self.状态机字典:
            raise ValueError(f"状态机管理器：{状态机名称} 不存在")
        return self.状态机字典[状态机名称]
    def 获取当前状态机(self):
        if len(self.状态机字典) == 0:
            raise ValueError("状态机管理器中没有状态机")
        if self.当前状态机名称 is None:
            self.当前状态机名称 = list(self.状态机字典.keys())[0]
        return self.状态机字典[self.当前状态机名称]


class 状态机:
    def __init__(self, 状态机管理器, 状态机名称: str):
        self.状态机管理器 = 状态机管理器
        self.状态机名称 = 状态机名称
        self.状态字典 = {}
        self.状态执行结果 = {}
        self.状态列表 = []
        self.当前状态索引 = None
        self.当前状态名称 = None
        self.调试模式 = False
        # 设置日志等级
        if self.调试模式:
            日志记录器.setLevel(logging.DEBUG)
            日志记录器.debug(f"{self.__class__.__name__}调试模式已开启")
        else:
            日志记录器.setLevel(logging.ERROR)  # 只显示警告及以上级别的日志

    def 注册状态(self, 状态名称: str, 连续状态=False):
        if 状态名称 in self.状态字典:
            raise ValueError(f"状态机：{self.状态机名称} 中状态：{状态名称} 已存在，无法重复注册")
        _状态 = 状态(self, 状态名称)
        self.状态字典[状态名称] = _状态
        self.状态执行结果[状态名称] = False
        if 连续状态:
            self.状态列表.append(_状态)
        return self.状态字典[状态名称]

    def 触发状态(self, 状态名称):
        if 状态名称 not in self.状态字典:
            raise ValueError(f"{self.状态机名称} 状态机中不存在状态：{状态名称}")
        self.状态字典[状态名称].执行状态动作()

    def 触发状态机状态变更(self, 状态):
        self.状态执行结果[状态.状态名称] = True
        if 状态 in self.状态列表:
            当前状态索引 = self.状态列表.index(状态)
            self.当前状态索引 = 当前状态索引
            if self.当前状态索引 < len(self.状态列表) - 1:
                self.状态列表[self.当前状态索引 + 1].执行状态动作()
        elif 状态 in self.状态字典:
            self.当前状态名称 = 状态.状态名称
        日志记录器.info(f"{self.状态机名称} 状态机当前状态：{self.获取当前状态名称()}")

    def 获取当前状态名称(self):
        if self.当前状态索引 is None:
            return self.当前状态名称
        return self.状态列表[self.当前状态索引].状态名称

    def 切换状态(self, 状态名称: str):
        if 状态名称 not in self.状态字典:
            raise ValueError(f"{self.状态机名称} 状态机中不存在状态：{状态名称}")
        self.状态字典[状态名称].执行状态动作()
    def 重置状态机(self):
        for 状态名称 in self.状态字典:
            self.状态执行结果[状态名称] = False
        self.当前状态索引 = None
        self.当前状态名称 = None


class 状态:
    def __init__(self, 状态机, 状态名称: str):
        self.状态机 = 状态机
        self.状态机管理器 = self.状态机.状态机管理器
        self.状态名称 = 状态名称
        self.状态描述 = None
        self.前置状态 = None
        self.后置状态 = None
        self.前置属性集合 = set()
        self.后置属性集合 = set()
        self.状态动作 = None
        self.调试模式 = False
        # 设置日志等级
        if self.调试模式:
            日志记录器.setLevel(logging.DEBUG)
            日志记录器.debug(f"{self.__class__.__name__}调试模式已开启")
        else:
            日志记录器.setLevel(logging.ERROR)  # 只显示警告及以上级别的日志

    def 前置属性注册(self, 属性名称: str):
        self.前置属性集合.add(属性名称)
        if self.状态机管理器.获取属性值(属性名称) is None:
            日志记录器.info(f"{self.状态机.状态机名称} 状态机中状态：{self.状态名称} 前置属性：{属性名称} 不存在，初始化为假")
            self.状态机管理器.设置属性(属性名称, False)
        self.状态机管理器.注册属性触发函数(属性名称, self.执行状态动作)

    def 后置属性注册(self, 属性名称: str):
        self.后置属性集合.add(属性名称)

    def 前置属性检查(self):
        日志记录器.debug(f"{self.状态机.状态机名称} 状态机中状态：{self.状态名称} 前置属性检查，前置属性集合：{self.前置属性集合}")
        for 属性名称 in self.前置属性集合:
            属性值 = self.状态机管理器.获取属性值(属性名称)
            if 属性值 is None:
                raise ValueError(f"{self.状态机.状态机名称} 状态机中状态：{self.状态名称} 前置属性：{属性名称} 不存在")
            if not 属性值:
                日志记录器.debug(f"{self.状态机.状态机名称} 状态机中状态：{self.状态名称} 前置属性：{属性名称} 为假，状态动作不执行")
                return False
        return True

    def 设置状态动作(self, 动作):
        if not callable(动作):
            raise TypeError(f"{self.状态机.状态机名称} 状态机中状态：{self.状态名称} 状态动作不是函数")
        self.状态动作 = 动作

    def 执行状态动作(self, 执行动作=True):
        日志记录器.info(f"{self.状态机.状态机名称} 状态机中状态：{self.状态名称} 状态动作执行")
        if self.状态机.状态执行结果[self.状态名称]:
            日志记录器.debug(f"{self.状态机.状态机名称} 状态机中状态：{self.状态名称} 状态已执行，不再执行")
            return True
        if not 执行动作:
            return False
        if not self.前置属性检查():
            日志记录器.info(f"{self.状态机.状态机名称} 状态机中状态：{self.状态名称} 前置属性未满足")
            return False
        if self.状态动作 is None:
            raise ValueError(f"{self.状态机.状态机名称} 状态机中状态：{self.状态名称} 状态动作未定义")
        if self.状态动作():
            for 属性名称 in self.后置属性集合:
                self.状态机管理器.设置属性触发函数(属性名称, True)
            self.状态机.触发状态机状态变更(self)
            return True
        日志记录器.debug(f"{self.状态机.状态机名称} 状态机中状态：{self.状态名称} 状态动作执行失败")
        return False
